package indi.gao.springAopTest.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>Description:</p>
 * <p>Copyright: Copyright (c)2020$</p>
 * <p>Company: Tope</p>
 * <P>Created Date :2020$-05$-18$</P>
 * <P>@version 1.0</P>
 */

@Aspect  //指定当前类为切面类
@Configuration
@Slf4j
public class AspectTest {

    /**
     * @throws Exception
     * @Description:指定 controller 包下面的所有方法中的所有方法
     * @create: 2020/5/18 12:36
     * @update logs
     */
    @Pointcut(value = "execution(* indi.gao.springAopTest.controller.*.*(..))")
    public void pointCutController() {
    }

    /**
     * @throws
     * @Description:@Around表示包围一个函数，也就是可以在函数执行前做一些事情，也可以在函数执行后做一些事情
     * @create: 2020/5/18 12:38
     * @update logs
     */
    @Around("pointCutController()")
    public Object controllerAround(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        log.info("controllerAround");
        log.info("类名{}", pjp.getTarget().getClass().getName());
        log.info("参数是{}", pjp.getArgs());
        log.info("方法名{}", pjp.getSignature());
        log.info("执行类型{}", pjp.getKind());
        Object proceed = pjp.proceed();
        log.info("返回值{}", proceed);
        return proceed;
    }

    @Before("pointCutController()")
    public void controllerBefore(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();
        log.info("controllerBefore");
        log.info("类名{}", joinPoint.getTarget().getClass().getName());
        log.info("请求路径{}", requestURI);
        log.info("参数是{}", joinPoint.getArgs());
        log.info("方法名{}", joinPoint.getSignature().getName());
        log.info("执行类型{}", joinPoint.getKind());
    }

    @After("pointCutController()")
    public void controllerAfter(JoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();
        log.info("controllerAfter");
        log.info("类名{}", joinPoint.getTarget().getClass().getName());
        log.info("请求路径{}", requestURI);
        log.info("参数是{}", joinPoint.getArgs());
        log.info("方法名{}", joinPoint.getSignature().getName());
        log.info("执行类型{}", joinPoint.getKind());
    }

    @Pointcut(value = "execution(* indi.gao.springAopTest.service.*.*(..))")
    public void pointCutService() {
    }

    @Around("pointCutService()")
    public Object serviceAround(ProceedingJoinPoint pjp) throws Throwable {
        log.info("serviceAround");
        log.info("类名{}", pjp.getTarget().getClass().getName());
        log.info("参数是{}", pjp.getArgs());
        log.info("方法名{}", pjp.getSignature().getName());
        log.info("执行类型{}", pjp.getKind());
        Object proceed = pjp.proceed();
        log.info("返回值{}", proceed);
        return proceed;
    }
}
